package io.yx.flx.handler;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.RuntimeUtil;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import cn.hutool.system.oshi.CpuInfo;
import cn.hutool.system.oshi.OshiUtil;
import io.vertx.core.Handler;
import io.vertx.core.http.HttpHeaders;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.web.RoutingContext;
import oshi.hardware.GlobalMemory;

import java.util.Queue;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ArrayBlockingQueue;

/**
 * index路由控制
 */
public class IndexHandler implements Handler<RoutingContext> {


    private static final int queueMax = 20;
    private static final Queue<JsonObject> systemLoad = new ArrayBlockingQueue<>(queueMax);


    static {
        /**
         * 每秒钟写入当前cpu负载
         */
        TimerTask task = new TimerTask() {
            @Override
            public void run() {
                String now = DateUtil.now();

                CpuInfo cpuInfo = OshiUtil.getCpuInfo();
                double cpuInfoUsed = cpuInfo.getUsed();

                GlobalMemory memoryInfo = OshiUtil.getMemory();
                long memoryTotal = memoryInfo.getTotal();
                long memoryAvailable = memoryInfo.getAvailable();
                long usedMem = memoryTotal - memoryAvailable;
                double memLoad = NumberUtil.mul(NumberUtil.div(usedMem, memoryTotal), 100);

                JsonObject queueItem = new JsonObject();
                queueItem.put("time", now).put("cpuLoad", cpuInfoUsed).put("memLoad", memLoad);
                if (systemLoad.size() == queueMax) {
                    systemLoad.poll();// 如果已满则移除一个
                }
                systemLoad.add(queueItem);
            }
        };
        Timer timer = new Timer("cpuInfoTask", true);
        timer.scheduleAtFixedRate(task, 0, 1000);// 每1000ms(1秒)执行一次获取cpu信息
    }

    private static final Log log = LogFactory.get();

    @Override
    public void handle(RoutingContext rc) {

        rc.response().putHeader(HttpHeaders.CONTENT_TYPE, "application/json;charset=utf-8");

        long totalMemory = RuntimeUtil.getTotalMemory();
        long maxMemory = RuntimeUtil.getMaxMemory();
        long freeMemory = RuntimeUtil.getFreeMemory();
        long usableMemory = RuntimeUtil.getUsableMemory();

        JsonObject resultJson = new JsonObject();

        JsonObject jvm = new JsonObject();
        jvm.put("totalMemory", totalMemory);
        jvm.put("maxMemory", maxMemory);
        jvm.put("freeMemory", freeMemory);
        jvm.put("usableMemory", usableMemory);
        resultJson.put("jvm", jvm);

        resultJson.put("systemLoad", systemLoad.toArray());

        rc.response().end(resultJson.toBuffer());
    }
}
